package com.mycase.im.boot.websocket.pattern.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.mycase.im.boot.entity.communication.ClientMessage;
import com.mycase.im.boot.entity.communication.ResponseMessage;
import com.mycase.im.boot.entity.database.ImChatGroup;
import com.mycase.im.boot.entity.database.ImChatGroupUser;
import com.mycase.im.boot.entity.database.ImMessage;
import com.mycase.im.boot.service.ChatGroupService;
import com.mycase.im.boot.service.ChatGroupUserService;
import com.mycase.im.boot.service.GroupMessageBodyService;
import com.mycase.im.boot.service.MessageService;
import com.mycase.im.boot.websocket.WebSocketSignal;
import com.mycase.im.boot.websocket.pattern.MessageStrategy;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.websocket.Session;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 用来处理邀请加入群聊的策略器
 * @Author ZhuHJay
 * @Date 2021/9/18 21:23
 */
@Slf4j
@Service
public class InviteJoinGroup implements MessageStrategy {

    @Autowired
    private ChatGroupService chatGroupService;
    @Autowired
    private ChatGroupUserService chatGroupUserService;
    @Autowired
    private MessageService messageService;
    @Autowired
    private GroupMessageBodyService groupMessageBodyService;

    @Override
    public Boolean isUse(int type) {
        return WebSocketSignal.MESSAGE_INVITE_JOIN_GROUP == type;
    }

    @Override
    public void executeHandler(ClientMessage clientMessage,
                               ObjectMapper objectMapper,
                               Map<String, Session> clientMaps,
                               Session mySession) throws Exception {
        log.warn("onMessage -匹配到-> InviteJoinGroup(邀请加入群聊)");

        // 通过群聊的id获取群的信息
        ImChatGroup chatGroupInfo = chatGroupService.getById(clientMessage.getGroupId());
        // 获取群聊的额外信息(群成员)
        List<ImChatGroupUser> groupUserList = chatGroupUserService.getGroupUserListById(chatGroupInfo.getId());
        chatGroupInfo.setGroupUsers(groupUserList);

        // 单独抽离新成员的消息
        List<ImChatGroupUser> beInviteUserList = new ArrayList<>();
        // 遍历群成员, 找到对应的人
        groupUserList.forEach(userInfo -> {
            // 如果能在id数组中找到对应的, 那么就存起来
            if( clientMessage.getBeInvitesId().indexOf(userInfo.getUserId()) != -1 ){
                beInviteUserList.add(userInfo);
            }
        });

        // 获取那几条邀请通知消息记录(先不进行群消息体的获取)
        List<ImMessage> inviteNotify =
                messageService.getInviteNotifyMessage(chatGroupInfo.getId(), clientMessage.getFromId(), beInviteUserList.size());

        /* 分为两种人:
            1. 被邀请人: 加入一个新的群聊, 需要一个群聊的信息(完整的信息)
            2. 接收消息的人: 已经在群聊中了, 需要更新群聊中的用户信息, 以及聊天记录
        */
        // 开始发送实时消息(给该群的所有成员发送, 但是他要在线)
        for (ImChatGroupUser imChatGroupUser : groupUserList) {
            String userId = imChatGroupUser.getUserId();
            // 判断是否在线
            if( clientMaps.containsKey(userId) ){
                // 判断是属于哪一类
                // 被邀请
                if( clientMessage.getBeInvitesId().indexOf(userId) != -1 ){
                    // 获取他在该群的所有聊天记录
                    messageService.getGroupMessageRecord(userId, chatGroupInfo);
                    // 发送出去
                    sendMessage(objectMapper, clientMaps.get(userId),
                                ResponseMessage.success()
                                        .appendData("groupInfo", chatGroupInfo)
                                        .appendData("type", WebSocketSignal.MESSAGE_INVITE_JOIN_GROUP)
                    );
                }
                // 存在群聊中的人, 需要获取新成员的信息, 以及通知消息
                else{
                    // 获取相对应的群消息体
                    inviteNotify.forEach(imMessage -> {
                        // 存储群消息体
                        imMessage.setImGroupMessageBody(
                                groupMessageBodyService.getOne(userId, imMessage.getToId()) );
                    });
                    // 发送出去
                    sendMessage(objectMapper, clientMaps.get(userId),
                                ResponseMessage.success()
                                        .appendData("imMessage", inviteNotify)
                                        .appendData("beInviteUserList", beInviteUserList)
                                        .appendData("type", WebSocketSignal.MESSAGE_INVITE_JOIN_GROUP)
                    );
                }
            }
        }
    }
}
